View Javadoc

1   // JoeqVM.java, created Sat Dec 14  2:52:34 2002 by mcmartin
2   // Copyright (C) 2001-3 jwhaley
3   // Licensed under the terms of the GNU LGPL; see COPYING for details.
4   package joeq.Main;
5   
6   import java.util.Iterator;
7   import joeq.Allocator.SimpleAllocator;
8   import joeq.Bootstrap.MethodInvocation;
9   import joeq.Class.PrimordialClassLoader;
10  import joeq.Class.jq_Class;
11  import joeq.Class.jq_NameAndDesc;
12  import joeq.Class.jq_StaticMethod;
13  import joeq.ClassLib.ClassLibInterface;
14  import joeq.Compiler.CompilationState;
15  import joeq.Compiler.CompilationState.DynamicCompilation;
16  import joeq.Runtime.Debug;
17  import joeq.Runtime.SystemInterface;
18  import joeq.Runtime.Unsafe;
19  import joeq.Scheduler.jq_InterrupterThread;
20  import joeq.Scheduler.jq_MainThread;
21  import joeq.Scheduler.jq_NativeThread;
22  import joeq.Scheduler.jq_Thread;
23  import joeq.UTF.Utf8;
24  import jwutil.strings.Strings;
25  import jwutil.util.Assert;
26  
27  /***
28   * @author  John Whaley <jwhaley@alum.mit.edu>
29   * @version $Id: JoeqVM.java 1941 2004-09-30 03:37:06Z joewhaley $
30   */
31  public abstract class JoeqVM {
32      public static void boot() throws Throwable {
33          try {
34              // initialize the thread data structures, allocators, etc.
35              jq_NativeThread.initInitialNativeThread();
36  
37              // init the ctrl-break handler thread.
38              jq_NativeThread.initBreakThread();
39  
40              // initialize dynamic compiler
41              CompilationState.DEFAULT = new DynamicCompilation();
42              
43              // call java.lang.System.initializeSystemClass()
44              ClassLibInterface.DEFAULT.initializeSystemClass();
45              
46          } catch (Throwable x) {
47              SystemInterface.debugwriteln("Exception occurred during virtual machine initialization");
48              SystemInterface.debugwriteln("Exception: " + x);
49              if (System.err != null) x.printStackTrace(System.err);
50              return;
51          }
52          
53          if (jq.on_vm_startup != null) {
54              Iterator it = jq.on_vm_startup.iterator();
55              while (it.hasNext()) {
56                  MethodInvocation mi = (MethodInvocation) it.next();
57                  try {
58                      mi.invoke();
59                  } catch (Throwable x) {
60                      SystemInterface.debugwriteln("Exception occurred while initializing the virtual machine");
61                      SystemInterface.debugwriteln(x.toString());
62                      x.printStackTrace(System.err);
63                      //return;
64                  }
65              }
66          }
67          
68          Debug.writeln("Joeq system initialized.");
69  
70          int numOfArgs = SystemInterface.main_argc();
71          String[] args = new String[numOfArgs];
72          for (int i = 0; i < numOfArgs; ++i) {
73              int len = SystemInterface.main_argv_length(i);
74              byte[] b = new byte[len];
75              SystemInterface.main_argv(i, b);
76              args[i] = new String(b);
77          }
78          String classpath = ".";
79          int i = 0;
80          for (; ;) {
81              if (i == args.length) {
82                  printUsage();
83                  return;
84              }
85              if (args[i].equals("-cp") || args[i].equals("-classpath")) { // class path
86                  classpath = args[++i];
87                  ++i;
88                  // update classpath here.
89                  if (classpath != null) {
90                      Iterator it = PrimordialClassLoader.classpaths(classpath);
91                      while (it.hasNext()) {
92                          String s = (String) it.next();
93                          PrimordialClassLoader.loader.addToClasspath(s);
94                      }
95                  }
96                  continue;
97              }
98              if (args[i].equals("-nt") || args[i].equals("-native_threads")) { // number of native threads
99                  jq.NumOfNativeThreads = Integer.parseInt(args[++i]);
100                 ++i;
101                 continue;
102             }
103             if (args[i].startsWith("-D")) { // system property
104                 String key;
105                 String value;
106                 int equals = args[i].indexOf('=');
107                 if (equals != -1) {
108                     key = args[i].substring(2, equals);
109                     value = args[i].substring(equals+1);
110                 } else {
111                     key = args[i].substring(2);
112                     value = "";
113                 }
114                 System.setProperty(key, value);
115                 ++i;
116                 continue;
117             }
118             if (args[i].startsWith("-mx")) { // max memory
119                 String amt = args[i].substring(3);
120                 int mult = 1;
121                 if (amt.endsWith("m") || amt.endsWith("M")) {
122                     mult = 1048576;
123                     amt = amt.substring(0, amt.length()-1);
124                 } else if (amt.endsWith("k") || amt.endsWith("K")) {
125                     mult = 1024;
126                     amt = amt.substring(0, amt.length()-1);
127                 }
128                 int size = mult * Integer.parseInt(amt);
129                 //size = HeapAddress.align(size, 20);
130                 SimpleAllocator.MAX_MEMORY = size;
131                 ++i;
132                 continue;
133             }
134             // todo: other command line switches to change VM behavior.
135             int j = TraceFlags.setTraceFlag(args, i);
136             if (i != j) {
137                 i = j;
138                 continue;
139             }
140             break;
141         }
142 
143         handleSystemProperties();
144         
145         jq_Thread tb = Unsafe.getThreadBlock();
146         jq_NativeThread nt = tb.getNativeThread();
147         jq_NativeThread.initNativeThreads(nt, jq.NumOfNativeThreads);
148 
149         // Here we start method replacement of classes whose name were given as arguments to -replace on the cmd line.
150         if (joeq.Class.jq_Class.TRACE_REPLACE_CLASS) SystemInterface.debugwriteln(Strings.lineSep+"STARTING REPLACEMENT of classes: " + joeq.Class.jq_Class.classToReplace);
151         for (Iterator it = joeq.Class.jq_Class.classToReplace.iterator(); it.hasNext();) {
152             String newCName = (String) it.next();
153             PrimordialClassLoader.loader.replaceClass(newCName);
154         }
155         if (joeq.Class.jq_Class.TRACE_REPLACE_CLASS) SystemInterface.debugwriteln(Strings.lineSep+"DONE with Classes Replacement!");
156 
157         String className = args[i];
158         jq_Class main_class = (jq_Class) PrimordialClassLoader.loader.getOrCreateBSType("L" + className.replace('.', '/') + ";");
159         main_class.load();
160         jq_StaticMethod main_method = main_class.getStaticMethod(new jq_NameAndDesc(Utf8.get("main"), Utf8.get("([Ljava/lang/String;)V")));
161         if (main_method == null) {
162             System.err.println("Class " + className + " does not contain a main method!");
163             return;
164         }
165         if (!main_method.isPublic()) {
166             System.err.println("Method " + main_method + " is not public!");
167             return;
168         }
169         main_class.cls_initialize();
170         String[] main_args = new String[args.length - i - 1];
171         System.arraycopy(args, i + 1, main_args, 0, main_args.length);
172 
173         //jq_CompiledCode main_cc = main_method.getDefaultCompiledVersion();
174         //Reflection.invokestatic_V(main_method, main_args);
175         jq_MainThread mt = new jq_MainThread(main_method, main_args);
176         mt.start();
177         jq_NativeThread.startNativeThreads();
178         nt.nativeThreadEntry();
179         Assert.UNREACHABLE();
180     }
181 
182     public static void handleSystemProperties() {
183         String s;
184         
185         s = System.getProperty("scheduler.quanta");
186         if (s != null) {
187             try {
188                 jq_InterrupterThread.QUANTA = Integer.parseInt(s);
189                 Debug.writeln("Scheduler quanta is ", jq_InterrupterThread.QUANTA);
190             } catch (NumberFormatException x) {
191                 Debug.writeln("Bad scheduler.quanta, ignoring.");
192             }
193         }
194         
195         s = System.getProperty("scheduler.transfer");
196         if (s != null) {
197             try {
198                 jq_NativeThread.TRANSFER_THRESHOLD = Float.parseFloat(s);
199                 Debug.write("Scheduler transfer threshold is ");
200                 System.err.println(jq_NativeThread.TRANSFER_THRESHOLD);
201             } catch (NumberFormatException x) {
202                 Debug.writeln("Bad scheduler.transfer, ignoring.");
203             }
204         }
205         
206         s = System.getProperty("scheduler.stack");
207         if (s != null) {
208             try {
209                 jq_Thread.INITIAL_STACK_SIZE = Integer.parseInt(s);
210                 Debug.writeln("Thread stack size is ", jq_Thread.INITIAL_STACK_SIZE);
211             } catch (NumberFormatException x) {
212                 Debug.writeln("Bad scheduler.stack, ignoring.");
213             }
214         }
215     }
216     
217     public static void printUsage() {
218         System.out.println("Usage: joeq <classname> <parameters>");
219     }
220 }